﻿#pragma once
#include "AsCoreGlobal.h"
#include <QObject>
#include <QColor>
#include <QVariant>
#include <QImage>
#include <QMargins>

class AsMicrosoftExcelPrivate;

struct AS_CORE_EXPORT AsMicrosoftExcelCell {
	AsMicrosoftExcelCell(const QVariant& value, int rowBegin, int rowEnd, int columnBegin, int columnEnd);
	AsMicrosoftExcelCell(const QVariant& value, int rowBegin, int rowEnd, const QString& columnBegin, int columnEnd);
	AsMicrosoftExcelCell(const QVariant& value, int rowBegin, int rowEnd, const QString& columnBegin, const QString& columnEnd);
	QVariant value;
	int rowBegin;
	int columnBegin;
	int rowSize;
	int columnSize;
};

class AS_CORE_EXPORT AsMicrosoftExcelAttributes {
public:
	enum Alignment {
		Left = -4131,
		Right = -4152,
		Top = -4160,
		Bottom = -4107,
		Center = -4108,
	};
	enum Flag {
		NoFlag = 0x00,
		Bold = 0x01,
		Italic = 0x02,
		Underline = 0x04,
		WrapText = 0x08,
		HorLeft = 0x10,
		HorRight = 0x20,
		HorCenter = 0x40,
		VerTop = 0x80,
		VerBottom = 0x100,
		VerCenter = 0x200,
		HVCenter = 0x400,
		AllReset = 0x800
	};

private:
	enum Type {
		Type_RowHeight, 
		Type_ColumnWidth, 
		Type_NumberFormat,
		Type_HorizontalAlignment, 
		Type_VerticalAlignment,
		Type_Bold, 
		Type_Italic, 
		Type_Underline, 
		Type_FontSize,
		Type_FontName, 
		Type_FontColor, 
		Type_BordersColor, 
		Type_BorderTopColor, 
		Type_BorderBottomColor, 
		Type_BorderLeftColor, 
		Type_BorderRightColor, 
		Type_BorderInsideHorColor,
		Type_BorderInsideVerColor,
		Type_DiagonalDownColor,
		Type_DiagonalUpColor,
		Type_BackgroundColor, 
		Type_WrapText
	};

public:
	AsMicrosoftExcelAttributes(unsigned int flag = NoFlag);

private:
	QMap<Type, QVariant> attributes;

public:
	void setFlag(unsigned int flag = NoFlag);
	void setRowHeight(float rowHeight = 14.25);
	void setColumnWidth(float columnWidth = 8.38);
	void setNumberFormat(const QString& format = "@");
	void setHorizontaAlignment(int alignment = Left);
	void setVerticalAlignment(int alignment = Top);
	void setBold(bool isBold = true);
	void setItalic(bool isItalic = true);
	void setUnderline(int underline = 1);
	void setFontSize(float fontSize = 11);
	void setFontName(const QString& fontName = "新宋体");
	void setFontColor(const QColor& fontColor = Qt::black);
	void setBordersColor(const QColor& bordersColor = QColor(212, 212, 212));
	void setBorderTopColor(const QColor& borderColor = QColor(212, 212, 212));
	void setBorderBottomColor(const QColor& borderColor = QColor(212, 212, 212));
	void setBorderLeftColor(const QColor& borderColor = QColor(212, 212, 212));
	void setBorderRightColor(const QColor& borderColor = QColor(212, 212, 212));
	void setBorderInsideHorColor(const QColor& borderColor = QColor(212, 212, 212));
	void setBorderInsideVerColor(const QColor& borderColor = QColor(212, 212, 212));
	void setDiagonalDownColor(const QColor& diagonalDownColor);
	void setDiagonalUpColor(const QColor& diagonalUpColor);
	void setBackgroundColor(const QColor& backgroundColor = Qt::white);
	void setWrapText(bool wrapText = true);
	void clear();

public:
	friend class AsMicrosoftExcelMethods;

};

class AS_CORE_EXPORT AsMicrosoftExcel : public QObject {
	Q_OBJECT
public:
	enum Flag {
		NoFlag			= 0x00,
		Visible			= 0x01,
		DisplayAlerts	= 0x02
	};

public:
	AsMicrosoftExcel(QObject* parent = nullptr);
	AsMicrosoftExcel(Flag flag, QObject* parent = nullptr);
	~AsMicrosoftExcel();

private:
	AsMicrosoftExcelPrivate* mp;

public:
	// 打开工作簿
	bool openWorkBook(const QString& filename = QString());
	// 新建工作簿
	bool addWorkBook(const QString& filename = QString(), const QString& oneSheetName = "Sheet1");
	// 保存工作簿
	bool saveWorkBook(const QString& filename = QString());
	// 选择工作表
	bool selectSheet(int number);
	// 删除工作表
	bool deleteSheet(int number);
	// 添加工作表
	bool addSheet(const QString& name);
	// 设置工作表名称
	bool setSheetName(int number, const QString& name);

public:
	// 设置获取单元格字符串
	QString getCellString(int row, int column);

public:
	// 设置单元格
	bool setCell(int row, int column, const QVariant& value, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCell(int row, int column, const QVariant& value, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCell(int row, const QString& column, const QVariant& value, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCell(const AsMicrosoftExcelCell& cell, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	
	// 设置单元格
	bool setCells(const QVector<QVector<QString>>& contents, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCells(const QVector<QVector<QString>>& contents, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCells(const QVector<AsMicrosoftExcelCell>& cells, int rowOffset = 0, int columnOffset = 0);
	// 设置单元格
	bool setCells(const QVector<AsMicrosoftExcelCell>& cells, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);

	// 设置行单元格
	void setRowCells(int row, int columnBegin, int columnEnd, const QVariant& value, const AsMicrosoftExcelAttributes& attributes = AsMicrosoftExcelAttributes());
	// 设置列单元格
	void setColumnCells(int column, int rowBegin, int rowEnd, const QVariant& value, const AsMicrosoftExcelAttributes& attributes = AsMicrosoftExcelAttributes());
	
	// 设置合并单元格
	void setMergeCell(int rowBegin, int rowEnd, int columnBegin, int columnEnd, const QVariant& value, const AsMicrosoftExcelAttributes& attributes = AsMicrosoftExcelAttributes(), int rowOffset = 0, int columnOffset = 0);
	void setMergeCell(int rowBegin, int rowEnd, const QString& columnBegin, const QString& columnEnd, const QVariant& value, const AsMicrosoftExcelAttributes& attributes = AsMicrosoftExcelAttributes(), int rowOffset = 0, int columnOffset = 0);
	
	// 添加图片
	void addPicture(int row, int column, QImage image, int x = 0, int y = 0, int width = -1, int height = -1, int rowOffset = 0, int columnOffset = 0);
	void addPicture(int row, const QString& column, QImage image, int x = 0, int y = 0, int width = -1, int height = -1, int rowOffset = 0, int columnOffset = 0);
	void addPicture(int rowBegin, int rowEnd, int columnBegin, int columnEnd, QImage image, const QMargins& margins = QMargins(), int rowOffset = 0, int columnOffset = 0);
	void addPicture(int rowBegin, int rowEnd, const QString& columnBegin, const QString& columnEnd, QImage image, const QMargins& margins = QMargins(), int rowOffset = 0, int columnOffset = 0);

	// 设置单元格属性
	void setProperty(int rowBegin, int rowEnd, int columnBegin, int columnEnd, const char* propertyName, const QVariant& param);
	// 设置单元格属性
	void setAttributes(int rowBegin, int rowEnd, int columnBegin, int columnEnd, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	void setAttributes(int rowBegin, int rowEnd, const QString& columnBegin, const QString& columnEnd, const AsMicrosoftExcelAttributes& attributes, int rowOffset = 0, int columnOffset = 0);
	
	// 设置行单元格属性
	void setRowAttributes(int row, const AsMicrosoftExcelAttributes& attributes);
	// 设置列单元格属性
	void setColumnAttributes(int column, const AsMicrosoftExcelAttributes& attributes);
	// 设置全部单元格属性
	void setAllAttributes(const AsMicrosoftExcelAttributes& attributes);
	
	// 合并单元格
	void mergeCell(int rowBegin, int rowEnd, int columnBegin, int columnEnd);
	void mergeCell(int rowBegin, int rowEnd, const QString& columnBegin, const QString& columnEnd);

	// 设置所用单元格自适应大小
	void setAutoFit();

public:
	// 支持多线程 -- 此操作应该在多线程中调用才会有效
	static void surportMultiThread();
	// 初始化Excel应用程序 -- 提前调用将节省构造时间
	// -- 此操作比较耗时，如果要使用此类功能，建议程序启动时主动使用线程调用，不主动调用将自动调用
	// -- 自动调用发生在此类的构造函数中，调用过程会有几秒钟的延时
	// -- 如果主动调用，此类构造时调用还未完成，那么当前线程会等待其调用完成
	// -- 当所有AsMicrosoftExcel类都被析构时，会自动执行反初始化
	static bool initExcelApplication();

};

namespace AsMicrosoft {

	typedef AsMicrosoftExcelAttributes AsAttributes;
	typedef AsMicrosoftExcelCell AsCell;
	typedef AsMicrosoftExcel AsExcel;

};